package com.check;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.fge.jsonschema.core.exceptions.ProcessingException;
import com.github.fge.jsonschema.core.report.ProcessingMessage;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.saasquatch.jsonschemainferrer.*;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Main {
    private static final ObjectMapper mapper = new ObjectMapper();
    private static final JsonSchemaInferrer inferrer = JsonSchemaInferrer.newBuilder()
            .setSpecVersion(SpecVersion.DRAFT_06)
            // Requires commons-validator
            .addFormatInferrers(FormatInferrers.email(), FormatInferrers.ip())
            .setAdditionalPropertiesPolicy(AdditionalPropertiesPolicies.notAllowed())
            .setRequiredPolicy(RequiredPolicies.nonNullCommonFields())
            .addEnumExtractors(EnumExtractors.validEnum(java.time.Month.class),
                    EnumExtractors.validEnum(java.time.DayOfWeek.class))
            .build();


    public static void main(String[] args) throws IOException, ProcessingException {
        String filePath = getPath();
        // 要基础的json文件
        String baseJsonFileName = args[0];
        // 要校验的json文件
        String checkJsonFileName = args[1];
        /*System.out.println("baseJsonFileName:" + baseJsonFileName);
        System.out.println("checkJsonFileName" + checkJsonFileName);
        System.out.println("通过baseJsonFile生成Schema文件");*/
        String baseJson = FileUtils.readFileToString(new File(filePath+ "//" +baseJsonFileName), "UTF-8");
        final JsonNode baseJsonNode = inferrer.inferForSample(mapper.readTree(baseJson));
        String jsonSchema = mapper.writeValueAsString(baseJsonNode);
        // System.out.println("Schema文件内容"+jsonSchema);

        String checkJson = FileUtils.readFileToString(new File(filePath+ "//" +checkJsonFileName), "UTF-8");

        ProcessingReport processingMessages = JsonCheckUtil.getProcessingMessages(jsonSchema, checkJson);

        if (!processingMessages.isSuccess()){
            System.out.println("数据存在问题,错误信息如下");
            //获取完整报告信息
            Iterator<ProcessingMessage> messages = processingMessages.iterator();


            for (Iterator<ProcessingMessage> it = messages; it.hasNext(); ) {
                ProcessingMessage message = it.next();
                System.out.println("--------------错误报告-------------");
                if ("type".equals(message.asJson().get("keyword").textValue())){
                    System.out.println("---------类型错误--------");
                    System.out.println("错误字段：" + message.asJson().get("instance"));
                    System.out.println("传入值：" + message.asJson().get("found"));
                    System.out.println("期待类型：" + message.asJson().get("expected"));
                } else if ("additionalProperties".equals(message.asJson().get("keyword").textValue())){
                    System.out.println("---------多余字段--------");
                    System.out.println("多余字段：" + message.asJson().get("unwanted"));
                }else if ("required".equals(message.asJson().get("keyword").textValue())){
                    System.out.println("---------缺少字段--------");
                    System.out.println("缺少字段：" + message.asJson().get("missing"));
                }
                System.out.println();
                System.out.println("--------------错误报告End-------------");
            }
        } else {
            System.out.println("检测通过");
        }

    }

    private static String getPath(){
        try {
            //获取当前类所在路径
            String path = new Main().getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
            //解决中文路径
            path = java.net.URLDecoder.decode(path,"UTF-8");
            //把路径切换到jar包所在位置
            File file = new File(path);
            path = file.getParentFile().getPath();
            //路径里可能会以file:\E:\xxx\ 显示 需要过虑出正确地址
            path = path.replace("file:\\","").replace("file:","");
            return path;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }
}
